package com.evendai.sipdemo.sip.audio

import android.content.BroadcastReceiver
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
import com.evendai.loglibrary.Timber
import com.evendai.sipdemo.App
import com.evendai.sipdemo.Constants
import com.evendai.sipdemo.bean.EnterGroup
import com.evendai.sipdemo.util.JsonUtil
import com.evendai.sipdemo.util.SipUtil
import org.doubango.ngn.NgnEngine
import org.doubango.ngn.events.NgnInviteEventArgs
import org.doubango.ngn.events.NgnInviteEventTypes
import org.doubango.ngn.media.NgnMediaType
import org.doubango.ngn.sip.NgnAVSession

/** 对讲组帮助类 */
object TalkbackGroupHelper: BroadcastReceiver() {

    private var groupSessionMap = mutableMapOf<String, NgnAVSession>()
    private var isRegistered = false

    override fun onReceive(context: Context, intent: Intent) {
        val args = intent.getParcelableExtra<NgnInviteEventArgs>(NgnInviteEventArgs.EXTRA_EMBEDDED)
        var groupSipCode : String? = null
        groupSessionMap.forEach {
            if (args?.sessionId != null && it.value.id == args.sessionId) {
                groupSipCode = it.key
            }
        }

        if (groupSipCode == null) {
            return
        }

        if (intent.action != NgnInviteEventArgs.ACTION_INVITE_EVENT || args!!.eventType == null || args.mediaType != NgnMediaType.Audio) {
            Timber.e("呼叫参数无效"); return
        }

        if (args.eventType == NgnInviteEventTypes.CONNECTED) {
            Timber.e("联指会议已拨通，会话id：${args.sessionId}")
            SipUtil.requestSpeakPermission(groupSipCode!!)
        }  else if (args.eventType == NgnInviteEventTypes.TERMINATED) {
            Timber.e("已退出联指会议，会话id：${args.sessionId}")
            groupSessionMap.remove(groupSipCode)
        }
    }

    /**
     * 进入对讲组
     * @param enterGroupRequestJson 进入指定对讲组的请求消息json
     */
    fun enterGroup(enterGroupRequestJson: String) {
        Timber.i("收到进组命令：$enterGroupRequestJson")
        val enterGroup = JsonUtil.json2Bean(enterGroupRequestJson, EnterGroup::class.java)
        if (enterGroup == null || enterGroup.bgroup.isNullOrBlank()) {
            Timber.fw("进组命令无法解析，json = $enterGroupRequestJson")
            return
        }

        if (groupSessionMap[enterGroup.bgroup]?.isActive == true) {
            // 此会议已经拨通了, 无需再拨
            Timber.i("会议${enterGroup.bgroup}已经拨通, 无需再拨, 需求来自: ${enterGroup.ipphone}")
            return
        }

        // 注册呼叫状态监听器
        if (!isRegistered) {
            isRegistered = true
            App.getContext().registerReceiver(this, IntentFilter(NgnInviteEventArgs.ACTION_INVITE_EVENT))
        }

        groupSessionMap[enterGroup.bgroup]?.hangUpCall()
        val groupAVSession = NgnAVSession.createOutgoingSession(NgnEngine.getInstance().sipService.sipStack, NgnMediaType.Audio)
        groupSessionMap[enterGroup.bgroup] = groupAVSession

        val conferenceNumber = Constants.pttmeeting + enterGroup.bgroup
        val validSipUri = SipUtil.makeValidSipUri(conferenceNumber)
        groupAVSession.remotePartyUri = validSipUri // HACK
        groupAVSession.makeCall(validSipUri)
        groupAVSession.setSpeakerphoneOn(Constants.sSpeakerphoneOn)
        Timber.e("已呼出联指会议，会话id为：${groupAVSession.id}，会议号为：${enterGroup.bgroup}")
    }

    /** 挂断指定的对讲组 */
    fun hangUpGroup(groupSipCode: String) {
        groupSessionMap.remove(groupSipCode)?.hangUpCall()
    }

    /** 挂断所有对讲组 */
    fun hangUpAll() {
        if (isRegistered) {
            App.getContext().unregisterReceiver(this)
        }

        groupSessionMap.forEach {
            if (it.value.isActive) {
                it.value.hangUpCall()
            }
        }

        groupSessionMap.clear()
    }

}